package avicit.bdp.dds.api.controller;

import avicit.bdp.dds.api.dto.ProcessNodeDto;
import avicit.bdp.dds.api.dto.TableSelectDto;
import avicit.bdp.dds.api.service.ModelService;
import avicit.bdp.dds.api.service.TaskNodesService;
import avicit.platform6.core.exception.BusinessException;
import avicit.platform6.core.rest.msg.ResponseMsg;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.List;
import java.util.Map;

/**
 * 模型相关contorller
 */
@RestController
@Api(tags = "模型相关REST接口")
@RequestMapping("/api/bdp/dds/model/")
public class ModelRest {

    @Autowired
    private ModelService modelService;
    @Autowired
    private TaskNodesService taskNodesService;

    /**
     * 数据源模型导入
     *
     * @param queryMap 请求体
     */
    @ApiOperation(value = "数据源模型导入")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tables", value = "表名称集合，逗号分隔", dataType = "String", paramType = "body", required = true),
            @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String", paramType = "body", required = true),
            @ApiImplicitParam(name = "typeId", value = "分类id", dataType = "String", paramType = "body", required = true),
            @ApiImplicitParam(name = "dataSourceId", value = "数据源id", dataType = "String", paramType = "body", required = true)
    })
    @PostMapping(value = "/importModel")
    public ResponseMsg<Map<String, List<String>>> importModel(@ApiIgnore @RequestBody Map<String, String> queryMap) {
        String tables = MapUtils.getString(queryMap, "tables", "");
        String projectId = MapUtils.getString(queryMap, "projectId", "");
        String typeId = MapUtils.getString(queryMap, "typeId", "");
        String dataSourceId = MapUtils.getString(queryMap, "dataSourceId", "");

        if (StringUtils.isAnyBlank(dataSourceId, tables, projectId, typeId)) {
            throw new BusinessException("请检查参数!");
        }
        ResponseMsg<Map<String, List<String>>> responseMsg = new ResponseMsg<>();

        //校验相同分类下表名是否重复
        String errorInfo = modelService.validateModelName(tables, projectId, typeId);
        if(StringUtils.isNotBlank(errorInfo)){
            responseMsg.setResponseBody(null);
            responseMsg.setMessage(errorInfo);
            return responseMsg;
        }
        responseMsg.setResponseBody(modelService.importModel(dataSourceId, tables, projectId, typeId));
        return responseMsg;
    }

    /**
     * 查询数据源模型导入状态
     */
    @ApiOperation(value = "查询数据源模型导入状态")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "dataSourceId", value = "数据源id", dataType = "String"),
            @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String"),
            @ApiImplicitParam(name = "typeId", value = "分类id", dataType = "String")
    })
    @GetMapping(value = "/queryTableAndStatus")
    public ResponseMsg<List<TableSelectDto>> queryTableAndStatus(@RequestParam("dataSourceId") String dataSourceId,
                                                                 @RequestParam("projectId") String projectId,
                                                                 @RequestParam("typeId") String typeId) throws Exception {
        if (StringUtils.isAnyBlank(dataSourceId, projectId, typeId)) {
            throw new BusinessException("请检查参数!");
        }
        ResponseMsg<List<TableSelectDto>> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(modelService.queryTableAndStatus(dataSourceId, projectId, typeId));
        return responseMsg;
    }

    /**
     * 获取流程模型树
     */
    @ApiOperation(value = "获取模型树")
    @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String")
    @GetMapping("/getProcessModelList")
    public ResponseMsg<List<ProcessNodeDto>> getProcessModelList(@RequestParam String projectId) {
        ResponseMsg<List<ProcessNodeDto>> responseMsg = new ResponseMsg<>();
        List<ProcessNodeDto> result = taskNodesService.getProcessModelList(projectId);
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    /**
     * 查询表数据列表
     */
    @ApiOperation(value = "查询表数据列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tableId", value = "表id", dataType = "String"),
            @ApiImplicitParam(name = "dataSourceId", value = "数据源id", dataType = "String"),
            @ApiImplicitParam(name = "sql", value = "sql脚本", dataType = "String")
    })
    @GetMapping(value = "/getDataListByTable")
    public ResponseMsg<Map<String, Object>> getDataListByTable(
            @RequestParam(value = "tableId", required = false) String tableId,
            @RequestParam(value = "dataSourceId", required = false) String dataSourceId,
            @RequestParam(value = "sql", required = false) String sql) throws UnsupportedEncodingException {

        ResponseMsg<Map<String, Object>> responseMsg = new ResponseMsg<>();

        if (StringUtils.isNotBlank(sql)) {
            sql = URLDecoder.decode(sql, "UTF-8");
        }

        if (StringUtils.isNotEmpty(sql) && !sql.trim().toLowerCase().startsWith("select")) {
            throw new BusinessException("该查询只支持查询语句！");
        }

        responseMsg.setResponseBody(modelService.getDataListByTable(tableId, dataSourceId, sql, 1, 100));
        return responseMsg;
    }


    /**
     * 分页查询表数据列表
     */
    @ApiOperation(value = "分页查询表数据列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "tableId", value = "表id", dataType = "String"),
            @ApiImplicitParam(name = "pageNo", value = "当前页", dataType = "Int"),
            @ApiImplicitParam(name = "pageSize", value = "每页大小", dataType = "Int")
    })
    @GetMapping(value = "/getDataListByTablePage")
    public ResponseMsg<Map<String, Object>> getDataListByTablePage(@RequestParam(value = "tableId") String tableId,
                                                                   @RequestParam(value = "pageNo", required = false) Integer pageNo,
                                                                   @RequestParam(value = "pageSize", required = false) Integer pageSize) {

        ResponseMsg<Map<String, Object>> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(modelService.getDataListByTable(tableId, null, null, pageNo, pageSize));
        return responseMsg;
    }

    /**
     * 下载表数据列表
     */
    @ApiOperation(value = "下载表数据列表")
    @ApiImplicitParam(name = "tableId", value = "表id", dataType = "String")
    @GetMapping(value = "/downloadTableData")
    public void downloadTableData(@RequestParam(value = "tableId") String tableId, HttpServletResponse response) {
        modelService.downloadTableData(tableId, response);
    }

}
